
#include "../coredef.h"

#include "cppdef.h"

#ifdef UNIT_TEST
#define static
#endif

#define VARI_ARG_KEYWORD  "__VA_ARGS__"
/************************************************************************/
/*  定数																	*/
/************************************************************************/
#define CTRL_TABLE_SIZE			128

/************************************************************************/
/*  グローバル変数															*/
/************************************************************************/




/************************************************************************/
/*  関数																	*/
/************************************************************************/

/************************************************************************/
/* 関 数 名 : cppDelAllDefArgSym											*/
/* 機    能 :	関数型マクロのパラメータ解析										*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	TRUE		正常終了											*/
/*			FALSE		致命エラー											*/
/************************************************************************/
static BOOL cppDelAllDefArgSym()
{
	return stCppMcrPrmLabelAccess.clear();
}

/************************************************************************/
/* 関 数 名 : cppDefFuncMacroExt											*/
/* 機    能 :	関数型マクロのパラメータ解析										*/
/* 引 き 数 : 	astMacroDef			マクロ定義情報								*/
/*			astArgStart			引数の開始位置								*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppDefFuncMacroExt(AST astMacroDef)
{
	U2	usTemp;
	AST		astTemp;
	U2	usTokenKind;
	AST		astParam;
	PSZ		pszTemp1;
	PSZ		pszTemp2;
	BOOL 	bBeforeRepSort = TRUE;			/* 置換要素並び前フラグ */
	BOOL 	bSSFlag = FALSE;				/* ＃＃フラグ */
	BOOL 	bSFlag = FALSE;					/* ＃フラグ */
	S4		nRet = COEXIT_SUCCESS;			/* 戻り値 */
	AST		astDefRepInfoIndex;				/* 置換要素情報連番 */
	U2	usRepSortIndex = 0;				/* 置換要素並び番号 */
	AST		astPreRepInfoIndex;				/* 直前の置換要素 */

	astDefRepInfoIndex = stCoreDefRepInfoAccess.getMax() + 1;

	while (nRet == COEXIT_SUCCESS) {
		/* 現在前処理字句の種類を取得 */
		usTokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );

		if (usTokenKind == xPPTOKEN_SHARPSHARP) {
			/* ##処理 */

			if (bBeforeRepSort == TRUE || usRepSortIndex == 0) {
				/* #define a ##a エラーコードCPP_DEF_SSLEFT_NOTFOUNDを警告する */
				CppThrowWarning( CPP_DEF_SSLEFT_NOTFOUND,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						NULL, NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

			if (bSFlag == TRUE) {
				/* #define a  # ## エラーコードCPP_DEF_SPARAM_ILLEGALを警告する */
				CppThrowWarning( CPP_DEF_SPARAM_ILLEGAL,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

			bSSFlag = TRUE;

			/* ##レベルアップ */
			astPreRepInfoIndex = stCoreDefRepInfoAccess.getMax();
			usTemp = stCoreDefRepInfoAccess.index.get(astPreRepInfoIndex);
			if (astDefRepInfoIndex <= astPreRepInfoIndex && usTemp == usRepSortIndex) {
				usTemp = stCoreDefRepInfoAccess.kind.get(astPreRepInfoIndex);
				if (usTemp == EXT_STRING) {
					usTemp = stCoreDefRepInfoAccess.kind.set( astPreRepInfoIndex, EXT_DSSTRING );
				}else if (usTemp == EXT_SSTRING) {
					usTemp = stCoreDefRepInfoAccess.kind.set( astPreRepInfoIndex, EXT_SSTRINGDS );
				}else if (usTemp == EXT_PARAM) {
					usTemp = stCoreDefRepInfoAccess.kind.set( astPreRepInfoIndex, EXT_DSPARAM );
				}else if (usTemp == EXT_SPARAM) {
					usTemp = stCoreDefRepInfoAccess.kind.set( astPreRepInfoIndex, EXT_SPARAMDS );
				}
			}else {
				/* エラーコードCPP_DEF_SSLEFT_NOTFOUNDを警告する */
				CppThrowWarning( CPP_DEF_SSLEFT_NOTFOUND,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						NULL, NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

		}else if (usTokenKind == xPPTOKEN_SHARP) {
			/* #処理 */

			if (bSFlag == TRUE) {
				/* #define a # # */
				CppThrowWarning( CPP_DEF_SPARAM_ILLEGAL,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

			if (bSSFlag == TRUE) {
				/* #define a ## # */

			}

			bSFlag = TRUE;

		}else {
			/* その他 */
			/* 引数かどうか確認 */
			astParam = 0;
			if (usTokenKind == xPPTOKEN_SYM) {
				pszTemp1 = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
				for (astTemp = 1; astTemp <= stCppMcrPrmLabelAccess.getMax(); astTemp ++) {
					pszTemp2 = stCppMcrPrmLabelAccess.name.get( astTemp );
					if (0 == strcmp(pszTemp1, pszTemp2)) {
						astParam = astTemp;
						break;
					}
				}
			}

			usRepSortIndex ++;
			/* KIND_DEFREPINFO追加 */
			FATAL_ON_FALSE(stCoreDefRepInfoAccess.alloc(1));

			astPreRepInfoIndex = stCoreDefRepInfoAccess.getMax();

			if (astParam >= MIN_ARRAY) {
				/* 引数 */
				stCoreDefRepInfoAccess.index.set(astPreRepInfoIndex, usRepSortIndex);

				if (bSFlag == TRUE) {
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_SPARAM);
				}else if (bSSFlag == TRUE) {
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_DSPARAM);
				}else {
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_PARAM);
				}
				astTemp =  stCppMcrPrmLabelAccess.index.get( astParam );
				stCoreDefRepInfoAccess.paramIdx.set( astPreRepInfoIndex, (S2)astTemp );
				astTemp = stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX);
				stCoreDefRepInfoAccess.location.set(astPreRepInfoIndex, astTemp);
			}else {
				/* 引数以外 */
				stCoreDefRepInfoAccess.index.set(astPreRepInfoIndex, usRepSortIndex);
				if (bSFlag == TRUE) {
					/* エラーコードCPP_DEF_SPARAM_ILLEGALを警告する */
					CppThrowWarning( CPP_DEF_SPARAM_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_SSTRING );
				}else if (bSSFlag == TRUE) {
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_DSSTRING );
				}else {
					stCoreDefRepInfoAccess.kind.set(astPreRepInfoIndex, EXT_STRING );
				}
				stCoreDefRepInfoAccess.ppTokenKind.set(astPreRepInfoIndex, usTokenKind);

				pszTemp1 = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
				stCoreDefRepInfoAccess.name.set(astPreRepInfoIndex, pszTemp1);

				astTemp = stCppTokenAccess.codeScp.get(CUR_TOKEN_INDEX);
				stCoreDefRepInfoAccess.location.set(astPreRepInfoIndex, astTemp);
			}

			/*  */
			bBeforeRepSort = FALSE;
			bSSFlag = FALSE;
			bSFlag = FALSE;
		}

		/* 次 */
		nRet = CppTokenGetNextToken( TRUE, FALSE );
	}

	/* 終了 */
	if (nRet == COEXIT_FINISHED) {
		nRet = COEXIT_SUCCESS;
	}

	if (bSSFlag == TRUE && nRet == COEXIT_SUCCESS ) {
		/* #define a a## エラーコードCPP_DEF_SSRIGHT_NOTFOUNDを警告する */
		CppThrowWarning( CPP_DEF_SSRIGHT_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX - 1),
				NULL, NULL );
		nRet = COEXIT_ERROR;
	}

	if (bSFlag == TRUE && nRet == COEXIT_SUCCESS ) {
		/* #define a(b) #  エラーコードCPP_DEF_SPARAM_ILLEGALを警告する */
		CppThrowWarning( CPP_DEF_SPARAM_ILLEGAL,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX - 1),
				NULL, NULL );
		nRet = COEXIT_ERROR;
	}

	astParam = stCoreDefRepInfoAccess.getMax();
	if (nRet != COEXIT_SUCCESS) {
		if (astDefRepInfoIndex <= astParam) {
			FATAL_ON_FALSE(stCoreDefRepInfoAccess.alloc(-(astParam - astDefRepInfoIndex + 1)));
		}
		return (nRet);
	}

	if (astDefRepInfoIndex <= astParam) {
		stCoreMacroDefInfoAccess.startReplaceEle.set(astMacroDef, astDefRepInfoIndex);
		stCoreMacroDefInfoAccess.endReplaceEle.set(astMacroDef, astParam);
	}

	return (COEXIT_SUCCESS);
}


/************************************************************************/
/* 関 数 名 : cppDefFuncMacro												*/
/* 機    能 :	関数型マクロの解析												*/
/* 引 き 数 : 	astMacroDef			マクロ定義情報								*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppDefFuncMacro(AST astMacroDef)
{
	S4 nCoRet;
	S4 nParamIndex;
	U2 usTokenKind;
	AST astNewDefSym;
	PSZ pszArgName;
	PSZ pszTemp;
//	PSZ pszMacroName;
	AST i;
	AST astMaxKind;
	AST astArgStart;			/* 仮引数の開始連番 */
	BOOL bArgCrash;
	BOOL bVariablePrm = FALSE;

	/* #define MACRO( <-ここまで ) */
	/* 引数登録 */
//	pszMacroName = stCoreMacroDefInfoAccess.macroName.get( astMacroDef );
	nParamIndex = 0;
	astArgStart = stCppMcrPrmLabelAccess.getMax();
	nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	while (nCoRet == COEXIT_SUCCESS) {
		/* 前処理字句の種類より処理 */
		usTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
		if (usTokenKind == xPPTOKEN_CLOSEPAREN) {
			/* 現在の前処理字句が「)」 */
			break;
		}else if( usTokenKind == xPPTOKEN_ELLIPSIS ){
			bVariablePrm = TRUE;
		}else if (usTokenKind != xPPTOKEN_SYM) {
			/* 現在の前処理字句がSYMBOLではない */
			CppThrowWarning( CPP_DEF_PARAMFORMAT_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			nCoRet = COEXIT_ERROR;
			continue;
		}

		/* 現在の前処理字句がSYMBOL */
		nParamIndex ++;
		if( bVariablePrm )
		{
			pszArgName = VARI_ARG_KEYWORD;
		}else{
			pszArgName = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
		}

		/* 重複チェック */
		bArgCrash = FALSE;
		astMaxKind = stCppMcrPrmLabelAccess.getMax();
		for (i = astArgStart + 1; i <= astMaxKind; i ++) {
			pszTemp = stCppMcrPrmLabelAccess.name.get(i);
			if (0 == strcmp(pszTemp, pszArgName)) {
				bArgCrash = TRUE;
				break;
			}
		}
		if (bArgCrash == TRUE) {
			/* エラーコード2307を警告する */
			CppThrowWarning( CPP_DEF_PARAM_DUPLICATE,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			nCoRet = COEXIT_ERROR;
			break;
		}

		/* DEFARGSYM追加 */
		FATAL_ON_FALSE(stCppMcrPrmLabelAccess.alloc(1));
		astNewDefSym = stCppMcrPrmLabelAccess.getMax();

		/* DEFARGSYM設定 */
		stCppMcrPrmLabelAccess.index.set(astNewDefSym, nParamIndex );

		stCppMcrPrmLabelAccess.name.set(astNewDefSym, pszArgName);
		/* 次 */
		nCoRet = CppTokenGetNextToken( TRUE, FALSE);
		usTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
		if ( bVariablePrm == FALSE && usTokenKind == xPPTOKEN_COMMA) {
					/* 現在の前処理字句が「,」 */
			nCoRet = CppTokenGetNextToken(TRUE,FALSE);
			continue;
		}else if (usTokenKind == xPPTOKEN_CLOSEPAREN) {

			break;
		}else{
			CppThrowWarning( CPP_DEF_PARAMFORMAT_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			nCoRet = COEXIT_ERROR;
			break;
		}
	}

	/* 戻り値はFATAL */
	if (nCoRet == COEXIT_FATAL) {
		cppDelAllDefArgSym();
		return (COEXIT_FATAL);
	}

	/* 戻り値はERROR */
	if (nCoRet == COEXIT_ERROR) {
		if (cppDelAllDefArgSym()) {
			return (COEXIT_ERROR);
		}else {
			return (COEXIT_FATAL);
		}
	}

	/* 終了判断 */
	nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	if (nCoRet == COEXIT_FINISHED) {
		/* 内容がない */
		if (cppDelAllDefArgSym()) {
			return (COEXIT_SUCCESS);
		}else {
			return (COEXIT_FATAL);
		}
	}else if (nCoRet != COEXIT_SUCCESS) {
		if (cppDelAllDefArgSym()) {
			return (nCoRet);
		}else {
			return (COEXIT_FATAL);
		}
	}

	/* 引数番号登録 */
	stCoreMacroDefInfoAccess.paramNum.set( astMacroDef, nParamIndex );
	stCoreMacroDefInfoAccess.bVariableParam.set( astMacroDef, bVariablePrm );
	/* 置き換え情報処理を行う */
	nCoRet = cppDefFuncMacroExt(astMacroDef);
	if (nCoRet == COEXIT_FINISHED) {
		nCoRet = COEXIT_SUCCESS;
	}

	/* クリア&リターン */
	if (cppDelAllDefArgSym()) {
		return (nCoRet);
	}else {
		return (COEXIT_FATAL);
	}
}


/************************************************************************/
/* 関 数 名 : cppDefObjMacro												*/
/* 機    能 :	オブジェクト型マクロの解析											*/
/* 引 き 数 : 	astMacroDef			マクロ定義情報								*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppDefObjMacro(AST astMacroDef)
{

	U2	usTemp;
	AST		astTemp;
	PSZ		pszTemp;
	U2	usTokenKind;
	AST		astPreRepIndex;				/* 直前の置換要素 */
	AST		astRepMax = 0;				/* 置き換え要素総数 */
	BOOL	bBeforeSort = TRUE;			/* 置き換え要素並び前フラグ */
	BOOL	bSSFlag = FALSE;			/* ＃＃フラグ */
	AST		astRepIndex = 0;			/* 置換要素情報連番 */
	U2	usRepSortIndex = 0;			/* 置換要素並び番号 */
	S4		nRet = COEXIT_SUCCESS;		/* 戻り値 */

	usTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if( usTokenKind == xPPTOKEN_HSPACE || usTokenKind == xPPTOKEN_VSPACE )
	{
		nRet = CppTokenGetNextToken( TRUE, FALSE);
	}
	/* 内容処理 */
	astRepIndex = stCoreDefRepInfoAccess.getMax() + 1;
	while (nRet == COEXIT_SUCCESS) {
		/* 現在の前処理字句より判断 */
		usTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);

		/* そのたの処理 */
		if (usTokenKind == xPPTOKEN_SHARPSHARP) {
			/* ##である */

			if (bBeforeSort == TRUE || usRepSortIndex == 0) {
				/* エラーコードCPP_DEF_SSLEFT_NOTFOUNDを警告する */
				CppThrowWarning( CPP_DEF_SSLEFT_NOTFOUND,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						NULL, NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

			if (bSSFlag == TRUE) {
				/* #define ## ##  == #define ##  */
			}

			bSSFlag = TRUE;

			astPreRepIndex = stCoreDefRepInfoAccess.getMax();
			usTemp =  stCoreDefRepInfoAccess.index.get(astPreRepIndex );
			if (astRepIndex <= astPreRepIndex && usTemp == usRepSortIndex) {
				usTemp = stCoreDefRepInfoAccess.kind.get( astPreRepIndex );
				if (usTemp == EXT_STRING) {
					stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_DSSTRING );
				}else if (usTemp == EXT_SSTRING) {
					stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_SSTRINGDS );
				}else if (usTemp == EXT_PARAM) {
					stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_DSPARAM );
				}else if (usTemp == EXT_SPARAM) {
					stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_SPARAMDS );
				}
			}else {
				CppThrowWarning( CPP_DEF_SSLEFT_NOTFOUND,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						NULL, NULL );
				nRet = COEXIT_ERROR;
				continue;
			}

		}else {
			/* ##ではない */
			/* DEFREPINFO追加 */
			usRepSortIndex ++;

			FATAL_ON_FALSE(stCoreDefRepInfoAccess.alloc(1));
			/* 設定 */
			astPreRepIndex = stCoreDefRepInfoAccess.getMax();
			stCoreDefRepInfoAccess.index.set( astPreRepIndex, usRepSortIndex );

			if (bSSFlag == TRUE) {
				stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_DSSTRING );
			}else {
				stCoreDefRepInfoAccess.kind.set( astPreRepIndex, EXT_STRING );
			}
			stCoreDefRepInfoAccess.ppTokenKind.set(astPreRepIndex, usTokenKind);

			pszTemp = stCppTokenAccess.name.get( CUR_TOKEN_INDEX ) ;
			stCoreDefRepInfoAccess.name.set( astPreRepIndex, pszTemp );

			astTemp =  stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			stCoreDefRepInfoAccess.location.set(astPreRepIndex, astTemp);

			/*  */
			bBeforeSort = FALSE;
			bSSFlag = FALSE;
		}

		/* 次 */
		nRet = CppTokenGetNextToken( TRUE, FALSE);
	}

	/* 終了判定 */
	if (nRet == COEXIT_FINISHED) {
		nRet = COEXIT_SUCCESS;
	}

	/*  */
	if (bSSFlag == TRUE&& nRet == COEXIT_SUCCESS ) {
		CppThrowWarning( CPP_DEF_SSRIGHT_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
				NULL, NULL );
		nRet = COEXIT_ERROR;
	}

	/* エラールート */
	astRepMax = stCoreDefRepInfoAccess.getMax();
	if (nRet != COEXIT_SUCCESS) {
		if (astRepIndex <= astRepMax) {
			FATAL_ON_FALSE(stCoreDefRepInfoAccess.alloc( -(astRepMax - astRepIndex + 1)));
		}
		return (nRet);
	}

	/* 成功ルート */
	if (astRepIndex <= astRepMax) {
		stCoreMacroDefInfoAccess.startReplaceEle.set( astMacroDef, astRepIndex );
		stCoreMacroDefInfoAccess.endReplaceEle.set( astMacroDef, astRepMax );
	}
	return (COEXIT_SUCCESS);
}


/************************************************************************/
/* 関 数 名 : cppDefInfoCmp												*/
/* 機    能 :	マクロ内容の比較												*/
/* 引 き 数 : 	astOri				比較元のMACRODEFINFOの連番					*/
/*			astDst				比較先のMACRODEFINFOの連番					*/
/* 戻 り 値 :	COMP_SAME			一致										*/
/*			COMP_DIFF			不一致									*/
/************************************************************************/
static S4 cppDefInfoCmp(AST astOri, AST astDst)
{
	BOOL	nOriDefined, nDstDefined;
	AST		nOriRepIdx, nDstRepIdx;
	AST		nOriRepLast, nDstRepLast;
	U2	usOriValue, usDstValue;
	S2	sOriValue, sDstValue;
	PSZ		pszOriValue;
	PSZ		pszDstValue;

	/* 定義のフラグを比較 */
	nOriDefined = stCoreMacroDefInfoAccess.bValid.get( astOri );
	nDstDefined = stCoreMacroDefInfoAccess.bValid.get( astDst );
	if (nOriDefined == FALSE || nDstDefined == FALSE) {
		return COMP_SAME;
	}

	/* マクロ種類を比較 */
	usOriValue = stCoreMacroDefInfoAccess.macroKind.get( astOri );
	usDstValue = stCoreMacroDefInfoAccess.macroKind.get( astDst );
	if (usOriValue != usDstValue) {
		return COMP_DIFF;
	}

	/* 関数型マクロの場合、引数の数を比較 */
	if (usOriValue == MACRO_FUNC) {
		sOriValue = stCoreMacroDefInfoAccess.paramNum.get( astOri );
		sDstValue = stCoreMacroDefInfoAccess.paramNum.get( astDst );
		if (sOriValue != sDstValue) {
			return COMP_DIFF;
		}
	}

	/* 最終手段：置き換え要素並びの比較 */
	nOriRepIdx = stCoreMacroDefInfoAccess.startReplaceEle.get( astOri );
	nDstRepIdx = stCoreMacroDefInfoAccess.startReplaceEle.get( astDst );
	nOriRepLast = stCoreMacroDefInfoAccess.endReplaceEle.get( astOri );
	nDstRepLast = stCoreMacroDefInfoAccess.endReplaceEle.get( astDst );
	if( nOriRepIdx == 0 && nDstRepIdx == 0 )
	{
		return COMP_SAME;
	}
	while (nOriRepIdx != 0 && nOriRepIdx <= nOriRepLast) {

		/* 比較先の方に対応する置換要素がなくなった */
		if (nDstRepIdx == 0 || nDstRepIdx > nDstRepLast) {
			return COMP_DIFF;
		}

		/* 置換要素の種類を比較する */
		usOriValue = stCoreDefRepInfoAccess.kind.get(nOriRepIdx);
		usDstValue = stCoreDefRepInfoAccess.kind.get(nDstRepIdx);
		if (usOriValue != usDstValue) {
			return COMP_DIFF;
		}

		/* 要素の内容を比較 */
		if (usOriValue == EXT_PARAM || usOriValue == EXT_DSPARAM || usOriValue == EXT_SPARAM || usOriValue == EXT_SPARAMDS) {
			/* 置換要素は引数の場合、引数番号を比較する */
			sOriValue = stCoreDefRepInfoAccess.paramIdx.get( nOriRepIdx ) ;
			sDstValue = stCoreDefRepInfoAccess.paramIdx.get( nDstRepIdx ) ;
			if (sOriValue != sDstValue) {
				return COMP_DIFF;
			}
		}else {
			/* 置換要素は引数ではない */

			/* 置換要素の前処理字句種類を比較する */
			usOriValue = stCoreDefRepInfoAccess.ppTokenKind.get(nOriRepIdx) ;
			usDstValue = stCoreDefRepInfoAccess.ppTokenKind.get(nDstRepIdx) ;
			if (usOriValue != usDstValue) {
				return COMP_DIFF;
			}

			/* 置換要素の前処理字句の文字列綴りを比較する */
			pszOriValue =  stCoreDefRepInfoAccess.name.get( nOriRepIdx );
			pszDstValue =  stCoreDefRepInfoAccess.name.get( nDstRepIdx );
			if (0 != strcmp(pszOriValue, pszDstValue)) {
				return COMP_DIFF;
			}
		}

		/* 次 */
		nOriRepIdx ++;
		nDstRepIdx ++;
	}

	/* 比較先の置換要素がまだ残っているかを判断 */
	if (nDstRepIdx <= nDstRepLast ) {
		return COMP_DIFF;
	}

	/* 一致と判断 */
	return COMP_SAME;
}


/****************************************************************************/
/* 関 数 名 : cppDefAddMacro													*/
/* 機    能 :	マクロの情報の追加													*/
/* 引 き 数 : 	iSearchValue		CppDefSearchMacroの戻り値						*/
/*			astMacroCtrl		CppDefSearchMacroで得たKIND_MACROCTRLの連番	*/
/*			astMacroDef			KIND_MACRODEFINFOの該当する行の連番				*/
/*			ibufCnt				bufMacroCtrlの添え字							*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了										*/
/*			COEXIT_FATAL		致命エラー										*/
/****************************************************************************/
static S4 cppDefAddMacro(BOOL bSearchValue, AST astMacroCtrl, AST astMacroDef )
{
	S4 iRet;
	AST nOriMacro;
	S4 nIsSameMacro;
	AST astDirInfo;
	if(bSearchValue) {
		/* マクロ重複定義 */

		/* 二つのマクロ情報を比較する */
		nOriMacro = stCppMacroCtrlAccess.macroInfo.get(astMacroCtrl);
		nIsSameMacro = cppDefInfoCmp(nOriMacro, astMacroDef);
		if (nIsSameMacro == COMP_DIFF) {
			/* 一致しない場合 */
			/* マクロ情報位置再設定 */
			astDirInfo = stCoreMacroDefInfoAccess.directiveInfo.get(astMacroDef);
			CppThrowWarning( CPP_DEF_MACRO_DUPLICATE,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo ),
					stCoreMacroDefInfoAccess.macroName.get( astMacroDef ), NULL );
			astDirInfo = stCoreMacroDefInfoAccess.directiveInfo.get(nOriMacro);
			CppThrowWarning( CPP_DEF_MACRO_DUPLICATE1ST,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo ),
					stCoreMacroDefInfoAccess.macroName.get( astMacroDef ), NULL );
			stCppMacroCtrlAccess.macroInfo.set( astMacroCtrl, astMacroDef );
		}else {
			/* 一致した場合 */

			/* マクロ情報位置再設定 */
			stCppMacroCtrlAccess.macroInfo.set( astMacroCtrl, astMacroDef );
		}
		iRet = COEXIT_SUCCESS;
	}
	else
	{
		iRet = stCppMacroCtrlAccess.addMacro( astMacroDef );

	}
	return iRet;
}
/************************************************************************/
/* 関 数 名 : CppDefSearchMacro											*/
/* 機    能 :	マクロ格納位置の検索												*/
/* 引 き 数 : 	pszMacroName		マクロ名									*/
/* 			pastMacroCtrl		取得したマクロ管理テーブル						*/
/* 戻 り 値 :	TRUE found                                                   */
/*            FALSE not found                                            */
/************************************************************************/
static BOOL cppDefSearchMacro(PSZ pszMacroName, AST *pastMacroCtrl)
{
	return stCppMacroCtrlAccess.findMacro( pszMacroName, pastMacroCtrl );

}

/************************************************************************/
/* 関 数 名 : CppDefSearchMacro											*/
/* 機    能 :	マクロ格納位置の検索												*/
/* 引 き 数 : 	pszMacroName		マクロ名									*/
/* 			pastMacroCtrl		取得したマクロ管理テーブル						*/
/* 戻 り 値 :	TRUE found                                                   */
/*            FALSE not found                                            */
/************************************************************************/
BOOL CppDefSearchMacro(PSZ pszMacroName, AST *pastMacroDef)
{
	AST astMacroCtrl = 0;
	BOOL ret = FALSE ;
	if( pastMacroDef != NULL ){
		ret = cppDefSearchMacro( pszMacroName, &astMacroCtrl );
		if( ret == TRUE )
		{
			*pastMacroDef = stCppMacroCtrlAccess.macroInfo.get( astMacroCtrl );
		}
		else
		{
			*pastMacroDef = 0;
		}
	}
	return ret;
}


/************************************************************************/
/* 関 数 名 : CppDefMain													*/
/* 機    能 :	#define処理													*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppDefMain(VOID)
{
	S4 i;
	AST nKindMax;
	S4 nCoRet = COEXIT_SUCCESS;
	AST nMacroCtrlIndex;
	BOOL bMacroCtrlFind;
	PSZ pszMacroName = NULL;
	AST nNewDirInfo = 0, nNewMacroDefInfo = 0;

	/* 処理必要な内容かどうか判断 */
	nKindMax = stCppDirectiveIFGroupAccess.getMax();
	if (TRUE != stCppDirectiveIFGroupAccess.state.get( nKindMax)) {
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}

	/* KIND_DIRECTIVEINFOに一行追加 */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	nNewDirInfo = stCoreDirectiveInfoAccess.getMax();

	/* DIRECTIVEの種類を設定 */
	stCoreDirectiveInfoAccess.kind.set(nNewDirInfo, CPPDEF_DEF );

	/* 位置情報取得し、設定 */
	nCoRet = CppLocSetDirectiveScope(nNewDirInfo);
	if( nCoRet != COEXIT_SUCCESS )
	{
		return nCoRet;
	}

	nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	if (nCoRet == COEXIT_FINISHED) {
		/* 前処理字句がない */
		CppThrowWarning( CPP_DEF_MACRONAME_NOTFOUND,
				stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
				NULL, NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}


	/* マクロ名確認 */
	if ( xPPTOKEN_SYM != stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX ) ) {
		CppThrowWarning( CPP_DEF_MACRONAME_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}else {
		pszMacroName = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
	}
	stCoreDirectiveInfoAccess.str_param.set(nNewDirInfo, pszMacroName );
	/* マクロ定義可能か否か確認 */
	nKindMax = stCppNestFileInfoAccess.getMax();
	if ( nKindMax>=MIN_ARRAY ) {
		/* ファイル中のマクロについて確認 */
		for (i = 0; stIndefinableMacro[i].pszMacroName != NULL; i ++) {
			if( stIndefinableMacro[i].bValid == 0 )
			{
				continue;
			}
			if (0 == strcmp(pszMacroName, stIndefinableMacro[i].pszMacroName)) {
				CppThrowWarning( CPP_DEF_MACRONAME_FORBIDDEN,
						stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
						pszMacroName, NULL );
				FATAL_ON_FATAL(CppTokensDelAll());
				return COEXIT_ERROR;
			}
		}
	}

	/* マクロは定義したマクロかどうかを確認 */
	bMacroCtrlFind = cppDefSearchMacro(pszMacroName, &nMacroCtrlIndex);

	/* MACRODEFINFO追加 */
	FATAL_ON_FALSE( stCoreMacroDefInfoAccess.alloc(1));
	nNewMacroDefInfo = stCoreMacroDefInfoAccess.getMax();

	/* MACRODEFINFO設定 */
	stCoreMacroDefInfoAccess.macroName.set(nNewMacroDefInfo, pszMacroName);
	stCoreMacroDefInfoAccess.bValid.set(nNewMacroDefInfo, TRUE);
	stCoreMacroDefInfoAccess.directiveInfo.set(nNewMacroDefInfo, nNewDirInfo);

	/* DIRECTIVEINFO設定 */
	stCoreDirectiveInfoAccess.idx_result.set(nNewDirInfo, nNewMacroDefInfo);

	/* マクロ種類より処理 */
	nCoRet = CppTokenGetNextToken( FALSE , FALSE);
	if (nCoRet == COEXIT_FINISHED) {
		/* 前処理字句がなくなった、マクロ名のみの定義 */
		stCoreMacroDefInfoAccess.macroKind.set(nNewMacroDefInfo, MACRO_OBJ);
		stCoreMacroDefInfoAccess.paramNum.set(nNewMacroDefInfo, -1);
		nCoRet = COEXIT_SUCCESS;

	}else if (xPPTOKEN_OPENPAREN == stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX ) ){
		/* 前処理字句が「（」である 、マクロ関数定義*/
		stCoreMacroDefInfoAccess.macroKind.set(nNewMacroDefInfo, MACRO_FUNC);
		nCoRet = cppDefFuncMacro(nNewMacroDefInfo);

	}else {
		/* 関数形ではない、定数マクロ定義 */
		stCoreMacroDefInfoAccess.macroKind.set(nNewMacroDefInfo, MACRO_OBJ);
		stCoreMacroDefInfoAccess.paramNum.set(nNewMacroDefInfo, -1);
		nCoRet = cppDefObjMacro(nNewMacroDefInfo);

	}

	/* トークンクリア */
	FATAL_ON_FATAL(CppTokensDelAll());

	/* マクロ解析成功かどうか判断 */
	if (nCoRet != COEXIT_SUCCESS) {
		/* 失敗した場合、該当情報を削除 */
		FATAL_ON_FALSE(stCoreMacroDefInfoAccess.alloc(-1));
		return (nCoRet);
	}

	/* マクロ追加 */
	pszMacroName = stCoreMacroDefInfoAccess.macroName.get( nNewMacroDefInfo ) ;
	nCoRet = cppDefAddMacro(bMacroCtrlFind, nMacroCtrlIndex, nNewMacroDefInfo );

	return (nCoRet);
}


/************************************************************************/
/* 関 数 名 : CppUndefMain													*/
/* 機    能 :	#undef処理													*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppUndefMain(VOID)
{
	S4 	i;
	AST nKindMax;
	S4 	nCoRet;
	AST 	nMacroCtrlIndex;
	BOOL 	bMacroCtrlFind;
	PSZ 	pszMacroName = NULL;
	AST 	nNewDirInfo = 0;
	AST	nNewMacroDefInfo = 0;

	/* 処理必要な内容かどうか判断 */
	nKindMax = stCppDirectiveIFGroupAccess.getMax();
	if (TRUE != stCppDirectiveIFGroupAccess.state.get( nKindMax ) ){
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}

	/* KIND_DIRECTIVEINFOに一行追加 */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	nNewDirInfo = stCoreDirectiveInfoAccess.getMax();

	/* DIRECTIVEの種類を設定 */
	stCoreDirectiveInfoAccess.kind.set(nNewDirInfo, CPPDEF_UNDEF);

	/* 位置情報取得し、設定 */
	nCoRet = CppLocSetDirectiveScope(nNewDirInfo);
	if( nCoRet != COEXIT_SUCCESS )
	{
		return nCoRet;
	}

	nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	if (nCoRet == COEXIT_FINISHED) {
		/* 前処理字句がない */
		CppThrowWarning( CPP_UND_MACRONAME_NOTFOUND,
				stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
				NULL, NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}

	/* マクロ名確認 */
	if ( xPPTOKEN_SYM != stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX ) ){
	/* マクロ名なしか無効の場合 */
		CppThrowWarning( CPP_UND_MACRONAME_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}else {
		pszMacroName = stCppTokenAccess.name.get( CUR_TOKEN_INDEX );
	}
	stCoreDirectiveInfoAccess.str_param.set(nNewDirInfo, pszMacroName );
	/* マクロ定義可能か否か確認 */
	nKindMax = stCppNestFileInfoAccess.getMax();
	if ( nKindMax>=MIN_ARRAY ) {
		/* ファイル中のマクロについて確認 */
		for (i = 0; stIndefinableMacro[i].pszMacroName != NULL; i ++) {
			if( stIndefinableMacro[i].bValid == 0 )
			{
				continue;
			}
			if (0 == strcmp(pszMacroName, stIndefinableMacro[i].pszMacroName)) {
				CppThrowWarning( CPP_UND_MACRONAME_FORBIDDEN,
						stCoreDirectiveInfoAccess.locScope.get( nNewDirInfo ),
						pszMacroName, NULL );
				FATAL_ON_FATAL(CppTokensDelAll());
				return COEXIT_ERROR;
			}
		}
	}

	/* マクロは定義したマクロかどうかを確認 */
	bMacroCtrlFind = cppDefSearchMacro(pszMacroName, &nMacroCtrlIndex);

	/* マクロすでに定義した場合 */
	if (bMacroCtrlFind  && nMacroCtrlIndex != 0) {
		nNewMacroDefInfo = stCppMacroCtrlAccess.macroInfo.get(nMacroCtrlIndex);
		stCoreDirectiveInfoAccess.idx_result.set(nNewDirInfo, nNewMacroDefInfo);
		stCoreMacroDefInfoAccess.bValid.set( nNewMacroDefInfo, FALSE );
	}

	/* 続きのチェック */
	nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	while (nCoRet == COEXIT_SUCCESS) {
		CppThrowWarning( CPP_UND_TOKEN_USELESS,
				stCppTokenAccess.codeScp.get( nNewDirInfo ),
				stCppTokenAccess.name.get( nNewDirInfo ), NULL );
		nCoRet = CppTokenGetNextToken( TRUE, FALSE);
	}

	/* クリア */
	FATAL_ON_FATAL(CppTokensDelAll());

	return COEXIT_SUCCESS;
}
